using System;
using System.Collections.Generic;
using System.Text;
using ImagesMath.Transformations;
using ImagesMath;

namespace Graphics
{
    public class Object3D : Entity
    {

        public Object3D() : base()
        {
            pForm = new Form();
            pMaterial = new Material();
            //geometry = new Geometry();
            
        }

        public Object3D( Form  pF, Material  pM, Transformation  pR ) 
        {
            pForm = pF;
            pMaterial= pM;
            pReferential = pR;
            //geometry = new Geometry();
        }

        public Form Form
        {
            get { return this.pForm; }
            set { pForm = value; }
        }

        public Material Material
        {
            get { return this.pMaterial; }
            set { pMaterial = value; }
        }

        public Transformation Referential
        {
            get { return this.pReferential; }
            set { pReferential = value; }
        }

        // move object, relative to its current location
        public void Move(float x, float y, float z)
        {
            this.Referential.T.X += x;
            this.Referential.T.Y += y;
            this.Referential.T.Z += z;
        }

        // place object in an absolute location within the world
        public void MoveTo(float x, float y, float z)
        {
            this.Referential.T.X = x;
            this.Referential.T.Y = y;
            this.Referential.T.Z = z;
        }

        // rotations (for each axis)
        //protected Vector3 m_Rotation = Vector3.Zero;
        private VR3 m_Rotation = new VR3(0, 0, 0);

        public VR3 Rotation
        {
            get { return m_Rotation; }
            set
            {
                m_Rotation = value;
                RotationUpdated();
            }
        }

        // rotate object, relative to current rotation
        public void Rotate(float pitch, float yaw, float roll)
        {
            m_Rotation.X += pitch;
            m_Rotation.Y += yaw;
            m_Rotation.Z += roll;

            // perform post-processing
            RotationUpdated();
        }

        // set absolute rotation
        public void RotateTo(float pitch, float yaw, float roll)
        {
            m_Rotation = new VR3(pitch, yaw, roll);

            // perform post-processing
            RotationUpdated();
        }

        public VR3 Location
        {
            get
            {
                return new VR3(this.Referential.T.X, this.Referential.T.Y, this.Referential.T.Z);
            }
            set
            {
                this.Referential.T.X = value.X;
                this.Referential.T.Y = value.Y;
                this.Referential.T.Z = value.Z;
            }
        }

        public Mesh Mesh
        {
            get { return mesh; }
            set { this.mesh = value; }
        }

        public BaseShader BaseShader
        {
            get { return shader; }
            set { this.shader = value; }
        }

        public virtual void RotationUpdated()
        {
            // override this method to handle rotation events
        }

        private Form pForm;
        private Material pMaterial;
        //private Geometry geometry;
        private Mesh mesh;
        private BaseShader shader;

    }
}

